home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Mac / Python / macgetpath.c < prev    next >
C/C++ Source or Header  |  1996-04-04  |  9KB  |  341 lines

  1. #include "Python.h"
  2. #include "osdefs.h"
  3.  
  4. #include "pythonresources.h"
  5.  
  6.  
  7. /* Return the initial python search path.  This is called once from
  8. ** initsys() to initialize sys.path.
  9. **
  10. ** If USE_BUILTIN_PATH is defined the path defined here is used
  11. ** (after prepending the python home dir to each item).
  12. ** If it is not defined the path is gotten from a resource in the
  13. ** Preferences file.
  14. **
  15. ** XXXX This code needs cleaning up. The routines here have moved
  16. ** around quite a bit, and they're pretty messy for that reason.
  17. */
  18.  
  19. #include <Files.h>
  20. #include <Aliases.h>
  21. #include <Folders.h>
  22. #include <Resources.h>
  23. #include <TextUtils.h>
  24. #include <Dialogs.h>
  25.  
  26. #define PYTHONPATH "\
  27. :\n\
  28. :Lib\n\
  29. :Lib:stdwin\n\
  30. :Lib:test\n\
  31. :Lib:mac"
  32.  
  33.  
  34. char *
  35. getpythonpath()
  36. {
  37.     /* Modified by Jack to do something a bit more sensible:
  38.     ** - Prepend the python home-directory (which is obtained from a Preferences
  39.     **   resource)
  40.     ** - Add :
  41.     */
  42.     static char *pythonpath;
  43.     char *curwd;
  44.     char *p, *endp;
  45.     int newlen;
  46.     staticforward char *PyMac_GetPythonDir();
  47. #ifndef USE_BUILTIN_PATH
  48.     staticforward char *PyMac_GetPythonPath();
  49. #endif
  50.     
  51.     if ( pythonpath ) return pythonpath;
  52.     curwd = PyMac_GetPythonDir();
  53. #ifndef USE_BUILTIN_PATH
  54.     if ( pythonpath = PyMac_GetPythonPath(curwd) )
  55.         return pythonpath;
  56.     printf("Warning: No pythonpath resource found, using builtin default\n");
  57. #endif
  58.     p = PYTHONPATH;
  59.     endp = p;
  60.     pythonpath = malloc(2);
  61.     if ( pythonpath == NULL ) return PYTHONPATH;
  62.     strcpy(pythonpath, ":");
  63.     while (*endp) {
  64.         endp = strchr(p, '\n');
  65.         if ( endp == NULL )
  66.             endp = p + strlen(p);
  67.         newlen = strlen(pythonpath) + 1 + strlen(curwd) + (endp-p);
  68.         pythonpath = realloc(pythonpath, newlen+1);
  69.         if ( pythonpath == NULL ) return PYTHONPATH;
  70.         strcat(pythonpath, "\n");
  71.         if ( *p == ':' ) {
  72.             p++;
  73.             strcat(pythonpath, curwd);
  74.             strncat(pythonpath, p, (endp-p));
  75.             newlen--;   /* Ok, ok, we've allocated one byte too much */
  76.         } else {
  77.             /* We've allocated too much in this case */
  78.             newlen -= strlen(curwd);
  79.             pythonpath = realloc(pythonpath, newlen+1);
  80.             if ( pythonpath == NULL ) return PYTHONPATH;
  81.             strncat(pythonpath, p, (endp-p));
  82.         }
  83.         pythonpath[newlen] = '\0';
  84.         p = endp + 1;
  85.     }
  86.     return pythonpath;
  87. }
  88.  
  89. /*
  90. ** Open/create the Python Preferences file, return the handle
  91. */
  92. static short
  93. PyMac_OpenPrefFile()
  94. {
  95.     AliasHandle handle;
  96.     FSSpec dirspec;
  97.     short prefrh;
  98.     short prefdirRefNum;
  99.     long prefdirDirID;
  100.     short action;
  101.     OSErr err;
  102.  
  103.     if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
  104.                     &prefdirDirID) != noErr ) {
  105.         /* Something wrong with preferences folder */
  106.         (void)StopAlert(NOPREFDIR_ID, NULL);
  107.         exit(1);
  108.     }
  109.     
  110.     (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
  111.     prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  112.     if ( prefrh < 0 ) {
  113.         action = CautionAlert(NOPREFFILE_ID, NULL);
  114.         if ( action == NOPREFFILE_NO )
  115.             exit(1);
  116.     
  117.         FSpCreateResFile(&dirspec, 'Pyth', 'pref', 0);
  118.         prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  119.         if ( prefrh == -1 ) {
  120.             /* This "cannot happen":-) */
  121.             printf("Cannot create preferences file, error %d\n", ResError());
  122.             exit(1);
  123.         }
  124.         if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
  125.             printf("Cannot get FSSpec for application, error %d\n", err);
  126.             exit(1);
  127.         }
  128.         dirspec.name[0] = 0;
  129.         if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
  130.             printf("Cannot make alias to application directory, error %d\n", err);
  131.             exit(1);
  132.         }
  133.         AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
  134.         UpdateResFile(prefrh);
  135.  
  136.     } else {
  137.         UseResFile(prefrh);
  138.     }
  139.     return prefrh;
  140. }
  141.  
  142. /*
  143. ** Return the name of the Python directory
  144. */
  145. static char *
  146. PyMac_GetPythonDir()
  147. {
  148.     static char name[256];
  149.     AliasHandle handle;
  150.     FSSpec dirspec;
  151.     Boolean modified = 0;
  152.     short oldrh, prefrh;
  153.     
  154.     oldrh = CurResFile();
  155.     /*
  156.     ** First look for an override of the preferences file
  157.     */
  158.     handle = (AliasHandle)GetResource('alis', PYTHONHOMEOVERRIDE_ID);
  159.     if ( handle != NULL ) {
  160.         prefrh = oldrh;
  161.     } else {
  162.         /*
  163.         ** Remember old resource file and try to open preferences file
  164.         ** in the preferences folder.
  165.         */
  166.         prefrh = PyMac_OpenPrefFile();
  167.         /* So, we've opened our preferences file, we hope. Look for the alias */
  168.         handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
  169.         if ( handle == NULL ) {
  170.             (void)StopAlert(BADPREFFILE_ID, NULL);
  171.             exit(1);
  172.         }
  173.     }
  174.     /* It exists. Resolve it (possibly updating it) */
  175.     if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
  176.         (void)StopAlert(BADPREFFILE_ID, NULL);
  177.         exit(1);
  178.     }
  179.     if ( modified ) {
  180.            ChangedResource((Handle)handle);
  181.         UpdateResFile(prefrh);
  182.     }
  183.     if ( prefrh != oldrh ) {
  184.            CloseResFile(prefrh);
  185.         UseResFile(oldrh);
  186.     }
  187.  
  188.        if ( nfullpath(&dirspec, name) == 0 ) {
  189.            strcat(name, ":");
  190.     } else {
  191.          /* If all fails, we return the current directory */
  192.            printf("Python home dir exists but I cannot find the pathname!!\n");
  193.         name[0] = 0;
  194.         (void)getwd(name);
  195.     }
  196.     return name;
  197. }
  198.  
  199. #ifndef USE_BUILTIN_PATH
  200. static char *
  201. PyMac_GetPythonPath(dir)
  202. char *dir;
  203. {
  204.     FSSpec dirspec;
  205.     short oldrh, prefrh = -1;
  206.     short prefdirRefNum;
  207.     long prefdirDirID;
  208.     char *rv;
  209.     int i, newlen;
  210.     Str255 pathitem;
  211.     int resource_id;
  212.     OSErr err;
  213.     
  214.     /*
  215.     ** Remember old resource file and try to open preferences file
  216.     ** in the preferences folder.
  217.     */
  218.     oldrh = CurResFile();
  219.     if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
  220.                     &prefdirDirID) == noErr ) {
  221.         (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
  222.         prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  223.     }
  224.     /* At this point, we may or may not have the preferences file open, and it
  225.     ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
  226.     ** exist we use the one from the application (the default).
  227.     ** We put an initial '\n' in front of the path that we don't return to the caller
  228.     */
  229.     if( (rv = malloc(2)) == NULL )
  230.         goto out;
  231.     strcpy(rv, "\n");
  232.     /*
  233.     ** See whether there's an override.
  234.     */
  235.     GetIndString(pathitem, PYTHONPATHOVERRIDE_ID, 1);
  236.     if ( pathitem[0] )
  237.         resource_id = PYTHONPATHOVERRIDE_ID;
  238.     else
  239.         resource_id = PYTHONPATH_ID;
  240.     for(i=1; ; i++) {
  241.         GetIndString(pathitem, resource_id, i);
  242.         if( pathitem[0] == 0 )
  243.             break;
  244.         if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
  245.             /* We have to put the directory in place */
  246.             newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
  247.             if( (rv=realloc(rv, newlen)) == NULL)
  248.                 goto out;
  249.             strcat(rv, dir);
  250.             /* Skip a colon at the beginning of the item */
  251.             if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
  252.                 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
  253.                 newlen--;
  254.             } else {
  255.                 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
  256.             }
  257.             rv[newlen-2] = '\n';
  258.             rv[newlen-1] = 0;
  259.         } else if ( pathitem[0] >= 14 && strncmp((char *)pathitem+1, "$(APPLICATION)", 14) == 0 ) {
  260.             /* This is the application itself */
  261.             char fullname[256];
  262.             
  263.             if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
  264.                 printf("Cannot get FSSpec for application, error %d\n", err);
  265.                 exit(1);
  266.             }
  267.             if ( nfullpath(&dirspec, fullname) != 0 ) {
  268.                 printf("Cannot convert application fsspec to path\n");
  269.                 exit(1);
  270.             }
  271.             newlen = strlen(rv) + strlen(fullname) + 2;
  272.             if( (rv=realloc(rv, newlen)) == NULL)
  273.                 goto out;
  274.             strcpy(rv+strlen(rv), fullname);
  275.             rv[newlen-2] = '\n';
  276.             rv[newlen-1] = 0;
  277.  
  278.         } else {
  279.             /* Use as-is */
  280.             newlen = strlen(rv) + (pathitem[0]) + 2;
  281.             if( (rv=realloc(rv, newlen)) == NULL)
  282.                 goto out;
  283.             memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
  284.             rv[newlen-2] = '\n';
  285.             rv[newlen-1] = 0;
  286.         }
  287.     }
  288.     if( strlen(rv) == 1) {
  289.         free(rv);
  290.         rv = NULL;
  291.     }
  292.     if ( rv ) {
  293.         rv[strlen(rv)-1] = 0;
  294.         rv++;
  295.     }
  296. out:
  297.     if ( prefrh ) {
  298.         CloseResFile(prefrh);
  299.         UseResFile(oldrh);
  300.     }
  301.     return rv;
  302. }
  303. #endif /* !USE_BUILTIN_PATH */
  304.  
  305. void
  306. PyMac_PreferenceOptions(int *inspect, int *verbose, int *suppress_print, 
  307.                          int *unbuffered, int *debugging, int *keep_normal,
  308.                          int *keep_error)
  309. {
  310.     short oldrh, prefrh;
  311.     Handle handle;
  312.     int size;
  313.     char *p;
  314.     
  315.     
  316.     oldrh = CurResFile();
  317.     prefrh = PyMac_OpenPrefFile();
  318.     handle = GetResource('Popt', PYTHONOPTIONSOVERRIDE_ID);
  319.     if ( handle == NULL )
  320.         handle = GetResource('Popt', PYTHONOPTIONS_ID);
  321.     if ( handle == NULL ) {
  322.         return;
  323.     }
  324.     HLock(handle);
  325.     size = GetHandleSize(handle);
  326.     p = (char *)*handle;
  327.     
  328.     if ( size > POPT_INSPECT ) *inspect = p[POPT_INSPECT];
  329.     if ( size > POPT_VERBOSE ) *verbose = p[POPT_VERBOSE];
  330.     if ( size > POPT_SUPPRESS ) *suppress_print = p[POPT_SUPPRESS];
  331.     if ( size > POPT_UNBUFFERED ) *unbuffered = p[POPT_UNBUFFERED];
  332.     if ( size > POPT_DEBUGGING ) *debugging = p[POPT_DEBUGGING];
  333.     if ( size > POPT_KEEPNORM ) *keep_normal = p[POPT_KEEPNORM];
  334.     if ( size > POPT_KEEPERR ) *keep_error = p[POPT_KEEPERR];
  335.     
  336.     HUnlock(handle);
  337.  
  338.        CloseResFile(prefrh);
  339.     UseResFile(oldrh);
  340. }
  341.